#include "cw32l010_sysctrl.h"
#include "cw32l010_gpio.h"
#include "cw32l010_uart.h"
#include "bsp_uart.h"

uart1_msg_t uart1_msg;

void uart_send_string(char *str)
{
	uint8_t len = strlen(str);
	uint8_t ll = len > UART_BUFF_SIZE ? UART_BUFF_SIZE : len;

	uart1_msg.buff_lenght = ll;
	uart1_msg.current_send = 0;
	memcpy(uart1_msg.buff, str, ll);
	UART_ITConfig(CW_UART1, UART_IT_TXE | UART_IT_TC, ENABLE);
	UART_ITConfig(CW_UART1, UART_IT_RC | UART_IT_RXIDLE, DISABLE);
}

/**
 * @brief 配置UART
 *
 */
void bsp_uart_init(void)
{

	memset(&uart1_msg, 0, sizeof(uart1_msg_t));

	UART1_DeInit();
	__SYSCTRL_UART1_CLK_ENABLE();
	__SYSCTRL_GPIOA_CLK_ENABLE();

	GPIO_InitTypeDef GPIO_InitStructure = {0};

	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Pins = GPIO_PIN_1;
	GPIO_Init(CW_GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
	GPIO_InitStructure.Pins = GPIO_PIN_0;
	GPIO_Init(CW_GPIOA, &GPIO_InitStructure);

	PA00_AFx_UART1RXD();
	PA01_AFx_UART1TXD();

	UART_InitTypeDef UART_InitStructure = {0};

	UART_InitStructure.UART_BaudRate = 115200;
	UART_InitStructure.UART_Over = UART_Over_16;
	UART_InitStructure.UART_Source = UART_Source_PCLK;
	UART_InitStructure.UART_UclkFreq = SystemCoreClock;
	UART_InitStructure.UART_StartBit = UART_StartBit_FE;
	UART_InitStructure.UART_StopBits = UART_StopBits_1;
	UART_InitStructure.UART_Parity = UART_Parity_No;
	UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
	UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx;

	UART_Init(CW_UART1, &UART_InitStructure);

	UART_ClearITPendingBit(CW_UART1, UART_IT_RC | UART_IT_TC);

	UART_ITConfig(CW_UART1, UART_IT_RC | UART_IT_RXIDLE, ENABLE);
	UART_ITConfig(CW_UART1, UART_IT_TC | UART_IT_TXE, DISABLE);

	// 优先级，无优先级分组
	NVIC_SetPriority(UART1_IRQn, 0);
	// UARTx中断使能
	NVIC_EnableIRQ(UART1_IRQn);
}

void UART1_IRQHandler(void)
{
	/* USER CODE BEGIN */

	if (UART_GetITStatus(CW_UART1, UART_IT_RC) != RESET && CW_UART1->IER_f.RC)
	{
		if (uart1_msg.current_recv < UART_BUFF_SIZE)
		{
			uart1_msg.state = MSG_RECV;
			uart1_msg.buff[uart1_msg.current_recv++] = UART_ReceiveData_8bit(CW_UART1);
		}

		UART_ClearITPendingBit(CW_UART1, UART_IT_RC);
	}
	if (UART_GetITStatus(CW_UART1, UART_IT_RXIDLE) != RESET && CW_UART1->IER_f.RXIDLE)
	{
		uart1_msg.state = MSG_RECV_COMP;
		uart1_msg.buff_lenght = uart1_msg.current_recv;
		UART_ClearITPendingBit(CW_UART1, UART_IT_RXIDLE);
	}

	if (UART_GetITStatus(CW_UART1, UART_IT_TXE) != RESET && CW_UART1->IER_f.TXE)
	{
		if (uart1_msg.buff_lenght)
		{
			uart1_msg.state = MSG_SEND;
			if (uart1_msg.current_send < uart1_msg.buff_lenght)
			{
				CW_UART1->TDR = uart1_msg.buff[uart1_msg.current_send++];
			}
			if (uart1_msg.current_send == uart1_msg.buff_lenght)
			{
				UART_ITConfig(CW_UART1, UART_IT_TXE, DISABLE);
			}
		}
	}

	if (UART_GetITStatus(CW_UART1, UART_IT_TC) != RESET && CW_UART1->IER_f.TC)
	{
		UART_ClearITPendingBit(CW_UART1, UART_IT_TC);

		if (uart1_msg.current_send == uart1_msg.buff_lenght)
		{
			uart1_msg.state = MSG_SNED_COMP;
			uart1_msg.current_send = 0;
			uart1_msg.buff_lenght = 0;
			uart1_msg.current_recv = 0;
			memset(uart1_msg.buff, 0, UART_BUFF_SIZE);

			UART_ITConfig(CW_UART1, UART_IT_TC, DISABLE);
			UART_ITConfig(CW_UART1, UART_IT_RC | UART_IT_RXIDLE, ENABLE);
		}
	}
	/* USER CODE END */
}

#if 1
/**
 * @brief Retargets the C library printf function to the UART.
 *
 */
int fputc(int ch, FILE *f)
{
	UART_SendData_8bit(CW_UART1, (uint8_t)ch);

	while (UART_GetFlagStatus(CW_UART1, UART_FLAG_TXE) == RESET)
		;

	return ch;
}

size_t __write(int handle, const unsigned char *buffer, size_t size)
{
	size_t nChars = 0;

	if (buffer == 0)
	{
		/*
		 * This means that we should flush internal buffers.  Since we
		 * don't we just return.  (Remember, "handle" == -1 means that all
		 * handles should be flushed.)
		 */
		return 0;
	}

	for (/* Empty */; size != 0; --size)
	{
		UART_SendData_8bit(CW_UART1, *buffer++);
		while (UART_GetFlagStatus(CW_UART1, UART_FLAG_TXE) == RESET)
			;
		++nChars;
	}

	return nChars;
}

#endif